from flask import Flask, render_template, request, jsonify
import pytest
import os
import json

app = Flask(__name__)

# 邮件配置参数
SMTP_SERVER = 'smtp.qq.com'  # SMTP服务器地址
SMTP_PORT = 587  # SMTP服务器端口（TLS）
EMAIL_FROM = '394522655@qq.com'  # 发件人邮箱地址
EMAIL_TO = '394522655@qq.com'  # 收件人邮箱地址
EMAIL_SUBJECT = 'Test Report'  # 邮件主题
EMAIL_USERNAME = '394522655@qq.com'  # 登录SMTP服务器的用户名
EMAIL_PASSWORD = 'xbokykrlnmovbhch'  # QQ邮箱的授权码

def get_docstring_from_nodeid(nodeid):
    """
    根据 nodeid 获取对应的测试函数的文档字符串。
    """
    try:
        parts = nodeid.split('::')
        module_path = parts[0].replace('.py', '').replace('/', '.').replace('\\', '.')
        class_name = parts[1] if len(parts) > 1 else None
        function_name = parts[-1]

        module = __import__(module_path, fromlist=[class_name])

        if class_name:
            cls = getattr(module, class_name)
            func = getattr(cls, function_name)
        else:
            func = getattr(module, function_name)

        raw_docstring = func.__doc__
        if raw_docstring:
            lines = raw_docstring.strip().split('\n')
            stripped_lines = [line.lstrip() for line in lines]
            return '\n'.join(stripped_lines)
        else:
            return ""
    except ImportError as e:
        print(f"无法导入模块: {e}")
        return ""
    except AttributeError as e:
        print(f"无法找到属性: {e}")
        return ""
    except Exception as e:
        print(f"无法获取文档字符串: {e}")
        return ""

def generate_html_report(reports_dir, report_filename, test_cases):
    """
    生成 HTML 报告文件。
    """
    report_path = os.path.join(reports_dir, report_filename)
    with open(report_path, 'w', encoding='utf-8') as file:
        file.write("<html>\n")
        file.write("  <head>\n")
        file.write("    <title>自动化测试报告</title>\n")
        file.write("    <script>\n")
        file.write("      function executeTestCase(nodeid) {\n")
        file.write("        fetch('/execute', {\n")
        file.write("          method: 'POST',\n")
        file.write("          headers: {\n")
        file.write("            'Content-Type': 'application/json'\n")
        file.write("          },\n")
        file.write("          body: JSON.stringify({nodeid: nodeid})\n")
        file.write("        }).then(response => response.json()).then(data => {\n")
        file.write("          alert(data.message);\n")
        file.write("        });\n")
        file.write("      }\n")
        file.write("    </script>\n")
        file.write("  </head>\n")
        file.write("  <body>\n")
        file.write("    <h1>898989898989</h1>\n")
        file.write("    <table border='1'>\n")
        file.write("      <tr><th>执行的用例ID</th><th>用例描述</th><th>操作</th></tr>\n")
        for case in test_cases:
            file.write(f"      <tr><td>{case['id']}</td><td>{case['description']}</td><td><button onclick=\"executeTestCase('{case['id']}')\">执行</button></td></tr>\n")
        file.write("    </table>\n")
        file.write("  </body>\n")
        file.write("</html>\n")
    return report_path

@app.route('/')
def index():
    script_dir = os.path.dirname(os.path.abspath(__file__))
    reports_dir = os.path.join(script_dir, 'reports')
    if not os.path.exists(reports_dir):
        os.makedirs(reports_dir)

    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    report_filename = f"test_report_{timestamp}.html"
    report_file = os.path.join(reports_dir, report_filename)

    json_report_file = os.path.join(reports_dir, 'report.json')

    pytest_args = [
        '-v',
        '--tb=short',
        '--json-report-file={}'.format(json_report_file),
        'tests/'
    ]

    pytest.main(pytest_args)

    if os.path.exists(json_report_file):
        with open(json_report_file, 'r', encoding='utf-8') as file:
            test_results = json.load(file)

        test_cases = []
        total_tests = 0
        passed_tests = 0

        for test_case in test_results.get('tests', []):
            nodeid = test_case.get('nodeid', '')
            outcome = test_case.get('outcome', '').lower()
            longrepr = test_case.get('longrepr', '')

            total_tests += 1

            description = get_docstring_from_nodeid(nodeid)

            status = "Passed" if outcome == 'passed' else "Failed"
            if status == "Passed":
                passed_tests += 1

            test_cases.append({
                "id": nodeid,
                "description": description,
                "status": status,
                "comment": longrepr
            })

        pass_rate = (passed_tests / total_tests) * 100 if total_tests > 0 else 0

        report_path = generate_html_report(reports_dir, report_filename, test_cases)

        with open(report_path, 'r', encoding='utf-8') as file:
            html_content = file.read()

        return html_content
    else:
        return "JSON 报告文件未找到。"

@app.route('/execute', methods=['POST'])
def execute_test_case():
    data = request.get_json()
    nodeid = data.get('nodeid')

    if nodeid:
        pytest_args = ['-k', nodeid, 'tests/']
        result = pytest.main(pytest_args)

        if result == 0:
            message = f"测试用例 {nodeid} 执行成功！"
        else:
            message = f"测试用例 {nodeid} 执行失败！"
    else:
        message = "无效的测试用例 ID。"

    return jsonify({"message": message})

if __name__ == '__main__':
    app.run(debug=True)